package com.atguigu.tingshu.user.service.impl;

import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.album.client.TrackInfoFeignClient;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.user.*;
import com.atguigu.tingshu.user.mapper.*;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private UserPaidAlbumMapper userPaidAlbumMapper;

    @Autowired
    private UserPaidTrackMapper userPaidTrackMapper;

    @Autowired
    private UserVipServiceMapper userVipServiceMapper;

    @Autowired
    private TrackInfoFeignClient trackInfoFeignClient;

    @Autowired
    private AlbumInfoFeignClient albumInfoFeignClient;

    @Autowired
    private VipServiceConfigMapper vipServiceConfigMapper;

    @Override
    public void updateVipExpireStatus() {
        //  先查询所有过期的用户信息. vip_expire_time<new date() and is_vip = 1
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getIsVip,1);
        wrapper.lt(UserInfo::getVipExpireTime,new Date());
        //  查询数据
        List<UserInfo> userInfoList = userInfoMapper.selectList(wrapper);
        //  属于vip 过期用户
        if (!CollectionUtils.isEmpty(userInfoList)){
            //  循环遍历
            userInfoList.stream().forEach(userInfo -> {
                //  修改vip状态位失效
                userInfo.setIsVip(0);
                //  userInfoMapper.updateById(userInfo);
            });
            //  更新vip
            this.saveOrUpdateBatch(userInfoList);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserPaidRecord(UserPaidRecordVo userPaidRecordVo) {
        //	判断用户购买类型 购买专辑
        if (userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_ALBUM)) {
            //	防止重复添加数据.
            Long count = userPaidAlbumMapper.selectCount(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getOrderNo, userPaidRecordVo.getOrderNo()));
            if (count > 0) return;
            //	插入数据 user_paid_album
            UserPaidAlbum userPaidAlbum = new UserPaidAlbum();
            userPaidAlbum.setOrderNo(userPaidRecordVo.getOrderNo());
            userPaidAlbum.setUserId(userPaidRecordVo.getUserId());
            //	赋值专辑Id
            userPaidAlbum.setAlbumId(userPaidRecordVo.getItemIdList().get(0));
            userPaidAlbumMapper.insert(userPaidAlbum);
        } else if (userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_TRACK)) {
            //  防止重复添加
            Long count = userPaidTrackMapper.selectCount(new LambdaQueryWrapper<UserPaidTrack>().eq(UserPaidTrack::getOrderNo, userPaidRecordVo.getOrderNo()));
            if (count > 0) return;
            //	获取专辑对象
            //	第一种方式：
            Result<TrackInfo> trackInfoResult = trackInfoFeignClient.getTrackInfo(userPaidRecordVo.getItemIdList().get(0));
            TrackInfo trackInfo = trackInfoResult.getData();
            //  第二种：
            //            Result<List<TrackInfo>> trackInfoResult = trackInfoFeignClient.findPaidTrackInfoList(userPaidRecordVo.getItemIdList().get(0), 0);
            //            List<TrackInfo> trackInfoList = trackInfoResult.getData();

            //	购买声音 user_paid_track
            userPaidRecordVo.getItemIdList().stream().forEach(trackId -> {
                //	创建对象
                UserPaidTrack userPaidTrack = new UserPaidTrack();
                userPaidTrack.setUserId(userPaidRecordVo.getUserId());
                userPaidTrack.setOrderNo(userPaidRecordVo.getOrderNo());
                userPaidTrack.setAlbumId(trackInfo.getAlbumId());
                userPaidTrack.setTrackId(trackId);
                //	保存数据
                userPaidTrackMapper.insert(userPaidTrack);
            });
        } else {
            //  防止重复
            Long count = userVipServiceMapper.selectCount(new LambdaQueryWrapper<UserVipService>().eq(UserVipService::getOrderNo, userPaidRecordVo.getOrderNo()));
            if (count > 0) return;

            //	购买vip user_vip_service
            UserVipService userVipService = new UserVipService();
            userVipService.setOrderNo(userPaidRecordVo.getOrderNo());
            userVipService.setUserId(userPaidRecordVo.getUserId());
            userVipService.setStartTime(new Date());
            //	设置过期时间：考虑当前用户是vip ，并且 还在有效期内，要实现续期操作.
            UserInfo userInfo = this.getById(userPaidRecordVo.getUserId());
            //	声明一个记录原来过期时间
            Date exprieTime = new Date();
            //	判断 考虑当前用户是vip ，并且 还在有效期内，要实现续期操作.
            if (userInfo.getIsVip().intValue() == 1 && userInfo.getVipExpireTime().after(new Date())) {
                //	赋值
                exprieTime = userInfo.getVipExpireTime();
            }
            //	计算过期时间：获取购买的时间;
            Long vipId = userPaidRecordVo.getItemIdList().get(0);
            VipServiceConfig vipServiceConfig = vipServiceConfigMapper.selectById(vipId);
            //  在原来的基础之上添加时间.
            Date newExpireTime = new DateTime(exprieTime).plusMonths(vipServiceConfig.getServiceMonth()).toDate();
            //  最新的过期时间
            userVipService.setExpireTime(newExpireTime);
            //	保存数据
            userVipServiceMapper.insert(userVipService);
            //	更新用户的信息；
            userInfo.setIsVip(1);
            userInfo.setVipExpireTime(newExpireTime);
            this.updateById(userInfo);
        }
    }

    @Override
    public List<Long> findUserPaidTrackList(Long userId, Long albumId) {
        //	select * from user_paid_track where user_id = ? and album_id = ?;
        List<Long> trackIdList = userPaidTrackMapper.selectList(new LambdaQueryWrapper<UserPaidTrack>().eq(UserPaidTrack::getAlbumId, albumId).eq(UserPaidTrack::getUserId, userId)).stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
        return trackIdList;
    }

    @Override
    public Boolean isPaidAlbum(Long userId, Long albumId) {
        //	如果用户购买过专辑，则会将记录信息存储到 user_paid_album
        LambdaQueryWrapper<UserPaidAlbum> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPaidAlbum::getAlbumId, albumId).eq(UserPaidAlbum::getUserId, userId);
        UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(wrapper);
        //	判断是否购买过
        if (null == userPaidAlbum) {
            return false;
        }
        return true;
    }

    /**
     * @param userId      用户Id
     * @param albumId     专辑Id
     * @param trackIdList 所以需要付费的声音Id 列表
     * @return
     */
    @Override
    public Map<Long, Integer> userIsPaidTrack(Long userId, Long albumId, List<Long> trackIdList) {
        //	user_paid_album 记录用户购买专辑
        //	select * from user_paid_album album where album.user_id = ? and album.album_id = ?;
        LambdaQueryWrapper<UserPaidAlbum> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPaidAlbum::getUserId, userId).eq(UserPaidAlbum::getAlbumId, albumId);
        UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(wrapper);
        //	判断
        if (null == userPaidAlbum) {
            //	创建一个map 集合
            Map<Long, Integer> map = new HashMap<>();
            //	查询用户是否购买过这个专辑对应的声音Id
            //	user_paid_track 记录用户购买声音
            //	select * from user_paid_track track where track.user_id = ? and track.track_id in (1,2);
            LambdaQueryWrapper<UserPaidTrack> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserPaidTrack::getUserId, userId).in(UserPaidTrack::getTrackId, trackIdList);
            //	表示获取到期这个用户已购买的声音集合列表！
            List<UserPaidTrack> userPaidNeedTrackList = userPaidTrackMapper.selectList(queryWrapper);
            Assert.notNull(userPaidNeedTrackList, "集合不为空");
            //	获取到已购买的声音Id 集合列表.
            List<Long> userPaidNeedTrackIdList = userPaidNeedTrackList.stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
            //	判断所有声音Id集合列表中是否包含已购买的声音Id
            //	trackIdList (6-55)  userPaidNeedTrackIdList(6-10)
            trackIdList.stream().forEach(trackId -> {
                //	已购买的声音Id集合列表中包含所有需要付费的声音Id
                if (userPaidNeedTrackIdList.contains(trackId)) {
                    //	给map 集合赋值 表示这个声音已购买
                    map.put(trackId, 1);
                } else {
                    //	表示这个声音没有购买
                    map.put(trackId, 0);
                }
            });
            //	返回map 集合
            return map;
        } else {
            //	创建一个map 集合
            Map<Long, Integer> map = new HashMap<>();
            //	说明这个用户有购买过专辑.
            trackIdList.forEach(trackId -> {
                //	1：已购买 0：未购买
                map.put(trackId, 1);
            });
            return map;
        }

    }

    @Override
    public UserInfoVo getUserInfo(Long userId) {
        //	创建UserInfoVo 对象
        UserInfoVo userInfoVo = new UserInfoVo();
        //	根据Id 获取用户数据
        UserInfo userInfo = userInfoMapper.selectById(userId);
        //	进行属性拷贝
        BeanUtils.copyProperties(userInfo, userInfoVo);
        //	返回数据
        return userInfoVo;
    }
}
